interface Person{
  name:string,
  readonly age:number
  sex:boolean
}

// in : 映射类型: 遍历
// keyof : 索引类型 每一个key取出来

type MyPartial<T> = {
  [P in keyof T]? : T[P]
}

// 只读 
let a : Person  = {name:'123',age:20,sex:true}

// a.age = 20;// readonly : 只能读 不能改
// 将 Person里面的所有的类型全部变成只读类型
// MyReadonly

type MyReadonly<T> = {
  readonly [P in keyof T] : T[P]
}


let pp : MyReadonly<Person> = {
  name:'',
  age:10,
  sex:true
}
// pp.name = '20'

// name : string
// sex : string 
// age : string
type MyRecord<T,U> = {
  [key in keyof T] : U
} 
let pp2 : MyRecord<Person,string> = {
  name : '124',
  age : '1244',
  sex : '1245'
}

type MyPick<T,U extends keyof T> ={
  [K in U] : T[K] // string number
}
let p:  MyPick<Person,'name'| 'age'>  ={
  name : '123',
  age : 20,
  // sex: true// Error
}
type PickPartial<T,U extends keyof T> = {
  [K in U]?: T[K]
}
let pp3 :PickPartial<Person,'name'|'age'> = {}// 取出来全部变成可选类型

// 作业 
// 发布订阅
// let publisher = new Publisher<IMessage>()
// 订阅
// publisher.subscribe({code : 10, (msg:IMessage)=>{console.log(console.log(msg))}})
// publisher.subscribe({code : 10, (msg:IMessage)=>{console.log(console.log(msg))}})
// publisher.subscribe({code : 10, (msg:IMessage)=>{console.log(console.log(msg))}})
// publisher.subscribe({code : 20, (msg:IMessage)=>{console.log(console.log(msg))}})
// 发布
// publisher.publish({code : 10},{msg:'hello'} as IMessage)